﻿//-------------------------------------------------------
// Copyright  lnc
// All rights reserved.
//
// File Name: CVecT.h
// File Des: Vec封装类 线程安全
// File Summary:
// Cur Version: 1.0
// Author:
// Create Data:
// History:
//      <Author>  <Time>      <Version>      <Des>
//      zeron    2021-6-24    1.0
//-------------------------------------------------------
#pragma once
#include "StlLockHelper.h"

/// <summary>
///        统一的Vec模板
/// </summary>
template <class TObj> class CVecT {
  typedef CStlLockHelper<std::vector<TObj>> VecType;
public:
  CVecT() {}
  virtual ~CVecT() { /*RemoveAll必须由重载函数的子类调用，不然重载函数无效*/
  }

  /// -------------------------------------------------
  /// @brief 获取数目
  /// @return 数目
  int GetCount() const { return (int)m_Vec.size(); }

  /// -------------------------------------------------
  /// @brief obj是否存在
  /// @param[in]         obj    用于查找的obj
  /// @return PP_INVALID_VALUE(-1)表示不存在
  int FindObj(const TObj& obj) const {
    MutexAutoLockObj(m_Vec);
    int count = (int)m_Vec.size();
    for (int i = 0; i < count; i++) {
      if (EqualVecObj(obj, m_Vec[i])) {
        return i;
      }
    }

    return -1;
  }

  /// -------------------------------------------------
  /// @brief 取得obj,
  /// @param[in]  iElement        指定项的index
  /// @param[out] obj                返回指定项的obj
  /// @remark 安全获取方式，推荐
  /// @return false:获取失败,true:获取成功
  bool GetObj(int iElement, TObj &obj) const {
    bool bRet = false;
    do {
      MutexAutoLockObj(m_Vec);
      if (iElement >= GetCount()) {
        break;
      }

      obj = m_Vec[iElement];
      bRet = true;
    } while (false);
    return true;
  }

  /// -------------------------------------------------
  /// @brief 取得obj
  /// @param[in] iElement           指定项的index
  /// @remark 不安全获取方式
  /// @return 获取的对象
  const TObj &GetObj(int iElement) const { return m_Vec[iElement]; }

  /// -------------------------------------------------
  /// @brief 加入obj
  /// @param[in] obj               加入指定项的obj
  /// @return true:加入成功,false:obj已存在
  bool AddObj(const TObj &obj) {
    bool bRet = false;
    do {
      MutexAutoLockObj(m_Vec);
      /// obj已存在
      if (-1 != FindObj(obj)) {
        break;
      }
      m_Vec.push_back(obj);
      bRet = true;
    } while (false);
    return bRet;
  }

  /// -------------------------------------------------
  /// @brief 移除obj
  /// @param[in] iElement        指定项的index
  /// @return true:移除成功,false:移除失败
  bool RemoveObj(int iElement) {
    bool bRet = false;
    do {
      if (iElement >= GetCount()) {
        break;
      }
      PreVecObjRemove(m_Vec[iElement]);
      m_Vec.erase(m_Vec.begin() + iElement);
      bRet = true;
    } while (false);
    return bRet;
  }

  /// -------------------------------------------------
  /// @brief 移除obj
  /// @param[in] obj        指定项obj
  /// @return true:移除成功,false:移除成功
  bool RemoveObj(const TObj &obj) {
    bool bRet = false;
    do {
      int iFind = FindObj(obj);
      // obj不存在
      if (-1 == iFind) {
        break;
      }
      PreVecObjRemove(obj);
      m_Vec.erase(m_Vec.begin() + iFind);
      bRet = true;
    } while (false);
    return bRet;
  }

  /// -------------------------------------------------
  /// @brief 移除所有obj
  /// @return 无
  void RemoveAll() {
    int count = GetCount();
    for (int i = 0; i < count; i++) {
      PreVecObjRemove(m_Vec[i]);
    }

    m_Vec.clear();
  }

  /// -------------------------------------------------
  /// @brief 可重载
  /// @remark 比较函数，由子类重载，默认直接==
  /// @return true:相等,false:不相等
  virtual bool EqualVecObj(const TObj &objsrc, const TObj &objdest) const {
    /// 外部子类重载
    if (objsrc == objdest) {
      return true;
    }
    return false;
  }

  /// -------------------------------------------------
  /// @brief 可重载
  /// @param[in] obj        指定项
  /// @remark 在移除前的预处理函数，用于子类重载
  /// @return 无
  virtual void PreVecObjRemove(const TObj &obj) {
    /// 外部子类重载
  }

public:
  VecType m_Vec;
};
